有一个仓库,可以存放 A 和 B 两种产品,仓库的存储空间足够大,但要求: (1)一次只能存入一种产品(A 或 B); (2)-N < (A 产品数量-B 产品数量) < M。 其中,N 和 M 是正整数。试用“存放 A”和“存放 B”以及 P、V 操作描述产品 A 与 产品 B 的入库过程。
Semaphore Sa = M - 1;
Semaphore Sb = N - 1;
//代表还能存入的数量
Semaphore mutex = 1;
process_A() {
while(1){
P(Sa); //取一个A产品准备入库
P(mutex);
A产品入库;
// A产品入库后还能存入A产品数量-1
V(mutex);
V(Sb); //还能存入B产品数量+1
}
}
process_B() {
while(1){
P(Sb); //取一个B产品准备入库
P(mutex);
B产品入库;
// B产品入库后还能存入B产品数量-1
V(mutex);
V(Sa); //还能存入A产品数量+1
}
}
桌子上有一只盘子,最多可容纳两个水果,每次只能放入或取出一个水果。爸爸专向盘子放苹果( apple),妈妈专向盘子中放桔子( orange);两个儿子专等吃盘子中的桔子,两个女儿专等吃盘子中的苹果。请用 P、 V 操作来实现爸爸、妈妈、儿子、女儿之间的同步与互斥关系。
Semaphore mutex = 1; //互斥信号量, 其初值为1
Semaphore empty = 2; //记录允许向盘子中放入水果的个数,初值为2
Semaphore orange = 0; //盘子中已放入的苹果的个数,初值为0
Semaphore apple = 0; //盘子中已放入的桔子的个数,初值为0
main()
{
Cobegin
{
father //父亲进程
{
while (true)
{
P(empty); //减少盘中可放入的水果数
P(mutex); //申请向盘中取、放水果
向盘中放苹果;
V(mutex); //允许向盘中取、放水果
V(apple); //递增盘中的苹果数
}
}
mother //母亲进程
{
while (true)
{
P(empty); //减少盘中可放入的水果数
P(mutex); //申请向盘中取、放水果
向盘中放桔子;
V(mutex); //允许向盘中取、放水果
V(orange); //递增盘中的桔子数
}
}
daughteri(i=1,2) //两女儿进程
{
while (true)
{
P(apple); //减少盘中苹果数
P(mutex); //申请向盘中取、放水果
取盘中苹果;
V(mutex); //允许向盘中取、放水果
V(empty); //递增盘中可放入的水果数
}
}
sonj(j=1,2) //两儿子进程
{
while (true)
{
P(orange); //减少盘中桔子数
P(mutex); //申请向盘中取、放水果
取盘中桔子;
V(mutex); //允许向盘中取、放水果
V(empty); //递增盘中可放入的水果数
}
}
}
Coend
}
有一个理发师,一把理发椅和 N 把供等候理发的顾客坐的椅子。如果没有顾客,则理发师便在理发师椅子上睡觉;当一个顾客到来时,必须唤醒理发师进行理发;如果理发师正在理发时又有顾客来到,则如果有空椅子可坐,他就坐下来等,如果没有空椅子,他就离开。为理发师和顾客各编一段程序(伪代码)描述他们的行为,要求不能带有竞争条件。
Semaphore mutex = 1; //互斥信号量,初值为1.
Semaphore Wait = 0; //等待服务的顾客数
Semaphore barbers= 0; //等待顾客的理发师数
Int custNum = 0; //等待的顾客(还没理发的)
Costumer()
{
while(true)
{
P(mutex); //申请理发
if(custNum>0)
{
if(custNum0)个单元的缓冲区。 P1 每次用 produce()生成一个正整数并用 put()送入缓冲区某一空单元中;P2 每次用 getodd()从该缓冲区中取出一个奇数并用 countodd()统计奇数个数;P3 每次用 geteven()从该缓冲区中取出一个偶数并用 counteven()统计偶数个数。请用信号量机制实现这三个进程的同步与互斥活动,并说明所定义信号量的含义。要求用伪代码描述。
P1()
{
While(true)
{
X = produce(); //生成一个数
P(empty); //是否有空单元格
P(mutex); //进入临界区
Put();
if(X%2 == 0)
V(s2); //如果是偶数,向P3发出信号
else
V(s1); //如果是奇数,向P2发出信号
V(mutex); //离开临界区,释放互斥信号量
}
}
P2()
{
While(true)
{
P(s1); //收到P1发送来的信号,已产生奇数
P(mutex); //进入临界区
getodd();
countodd():=countodd()+1;
V(mutex);
V(empty); //离开临界区,释放互斥信号量
}
}
P3()
{
While(true)
{
P(s2) //收到P1发送来的信号,已产生偶数
P(mutex); //进入临界区
geteven();
counteven():=counteven()+1;
V(mutex);
V(empty); //离开临界区,释放互斥信号量
}
}
|